package com.bdqn.base.auth;

import cn.hutool.http.HttpUtil;
import com.alibaba.fastjson.JSON;
import com.bdqn.base.R;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;

import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.List;

/**
 * WebAuthAspect Web认证切面
 *
 * @author LILIBO
 * @since 2022-04-26
 */
// @Aspect
@Slf4j
// @Component
public class WebAuthAspect {

    private static StringBuffer sb = new StringBuffer();

    /**
     * 切点（com.bdqn.Controller为切点）
     */
    // @Pointcut("execution(* com.bdqn.controller..*.*(..))")
    public void WebAuth() {
    }

    /**
     * 环绕通知
     */
    // @Around("WebAuth()")
    public Object doAround(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
        // 记录执行开始时间
        long startTime = System.currentTimeMillis();

        RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = (HttpServletRequest) requestAttributes.resolveReference(RequestAttributes.REFERENCE_REQUEST);

        // 配置放行的URI
        List<String> releaseUri = new ArrayList<>();
        releaseUri.add("/mail/verificationCode");
        releaseUri.add("/mail/smsCode");
        releaseUri.add("/order/test/1");

        String requestURI = request.getRequestURI();
        System.out.println(requestURI);
        if (releaseUri.contains(requestURI)) {
            return proceedingJoinPoint.proceed();
        }
        // 从Header中获取auth_token数据
        String token = request.getHeader("auth_token");
        if (token == null) {
            return R.failure("Token验证失败(code:1)");
        }
        // 去认证中心进行Token认证
        String response = HttpUtil.post("http://localhost:8000/auth/verify", token);
        if (response == null) {
            return R.failure("Token验证失败(code:2)");
        }
        // 解析响应的数据
        R r = JSON.parseObject(response, R.class);
        long endTime = System.currentTimeMillis();
        if (R.CODE_FAILURE == r.getCode() || !(boolean) r.getData()) {
            System.out.printf("%d (毫秒) Token验证失败 ------\n", (endTime - startTime));
            return R.failure("Token验证失败");
        }
        System.out.printf("%d (毫秒) Token验证通过 ------\n", (endTime - startTime));
        // 执行被代理的原方法
        return proceedingJoinPoint.proceed();
    }

}

